package jp.androidgroup.chiba.androidresearch.ui;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import jp.androidgroup.chiba.androidresearch.Common;
import jp.androidgroup.chiba.androidresearch.R;
import jp.androidgroup.chiba.androidresearch.data.Counter;
import jp.androidgroup.chiba.androidresearch.db.DatabaseHelper;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 過去の集計を編集するActivity
 *
 * @author noxi
 *
 */
public final class CounterEditActivity extends Activity implements AdapterView.OnItemClickListener {


	private static final String TAG = "CounterEditActivity";

	/**
	 * CounterAddActivityを呼び出すときのパラメーター
	 */
	private static final int REQUEST_ADD = 1;

	private ListAdapter mAdapter;
	private DatabaseHelper mHelper;

	private String mDate;
	private String mTime;
	private String mPlace;
	private String mMemo;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_counter_edit);

		// CounterActivityからパラメーターを受け取る
		Bundle extras = getIntent().getExtras();
		mDate = extras.getString(CounterActivity.EXTRA_DATE);
		mTime = extras.getString(CounterActivity.EXTRA_TIME);
		mPlace = extras.getString(CounterActivity.EXTRA_PLACE);
		mMemo = extras.getString(CounterActivity.EXTRA_MEMO);

		// 起動パラメーターが不正な場合
		if (mDate == null || mTime == null || mPlace == null || mMemo == null) {
			Log.e(TAG, "Launch value invalid");
			finish();
			return;
		} else {
			mHelper = new DatabaseHelper(this);
		}

		// DBからリストの取得
		try {
			initAdapter();
		} catch (SQLiteException e) {
			e.printStackTrace();
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
			finish();
			return;
		}

		// Widget取得
		ListView listView = (ListView) findViewById(R.id.list);
		// ヘッダー（集計の追加）
		View header = LayoutInflater.from(this)
				.inflate(R.layout.listitem_counter_edit, listView, false);
		TextView text = (TextView) header.findViewById(R.id.text);
		text.setText(R.string.l_add_entry);
		LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) text.getLayoutParams();
		params.gravity = Gravity.CENTER_HORIZONTAL;

		listView.addHeaderView(header, null, true);
		listView.setAdapter(mAdapter);
		listView.setOnItemClickListener(this);

		initTextView();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.counter_edit_activity, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		final int id = item.getItemId();
		if (id == R.id.menuitem_edit) {
			// ダイアログ表示
			try {
				new CounterInfoDialog(this, mDate, mTime, mPlace, mMemo,
						new CounterInfoDialog.OnClickListener() {

							@Override
							public void onPositiveClick(
									String date, String time, String place, String memo) {
								if (mDate.equals(date) && mTime.equals(time)
										&& mPlace.equals(place) && mMemo.equals(memo)) {
									return;
								}

								if (updateItemInDB(date, time, place, memo) == false) {
									Toast.makeText(CounterEditActivity.this,
											"更新に失敗しました", Toast.LENGTH_LONG).show(); // TODO
									return;
								}

								mDate = date;
								mTime = time;
								mPlace = place;
								mMemo = memo;

								initAdapter();
								initTextView();
							}

							@Override
							public void onNegativeClick() {}
						})
				.show();
			} catch (ParseException e) {
				e.printStackTrace();
			} catch (SQLiteException e) {
				e.printStackTrace();
			}
			return true;
		} else {
			return false;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case REQUEST_ADD:
			if (resultCode == RESULT_OK) {
				try {
					initAdapter();
				} catch (SQLiteException e) {
					e.printStackTrace();
					Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
					finish();
					return;
				}
			}
		}
	}

	/*
	 * ListViewをクリックした場合
	 * (non-Javadoc)
	 * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
	 */
	@Override
	public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
		// ヘッダー（項目の追加）
		if (position == 0) {
			// 日付・時間・場所をセット
			Counter counter = new Counter();
			counter.setContributeDate(mDate);
			counter.setTimeId(mTime);
			counter.setPlaceId(mPlace);
			counter.setMemo(mMemo);
			counter.setNum("1");
			// リスト保持
			counter.setDetails(mAdapter.getData());

			Intent intent = new Intent(this, CounterAddActivity.class);
			intent.putExtra(CounterAddActivity.EXTRA_COUNTER, counter);
			startActivityForResult(intent, REQUEST_ADD);
		}
		// 項目を選択
		else {
			new AlertDialog.Builder(this)
			.setItems(R.array.counter_list_detail, new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					Counter counter = mAdapter.getItem(position - 1);

					// 編集
					if (which == 0) {
						// Counterに今回選択された以外の項目をリストとして代入する
						List<Counter> list = new ArrayList<Counter>(mAdapter.getCount() - 1);
						for (int i = 0 ; i < mAdapter.getCount() ; i++) {
							Counter c = mAdapter.getItem(i);
							if (c.getId().equals(counter.getId())) {
								continue;
							} else {
								list.add(c);
							}
						}
						counter.setDetails(list);

						Intent intent = new Intent(
								CounterEditActivity.this, CounterAddActivity.class);
						intent.putExtra(CounterAddActivity.EXTRA_COUNTER, counter);
						startActivityForResult(intent, REQUEST_ADD);
					}
					// 削除
					else if (which == 1) {
						// DBから削除
						try {
							boolean delete = deleteItemFromDB(counter);
							if (delete == true) {
								// 表示リスト項目の削除
								mAdapter.remove(position - 1);
								mAdapter.notifyDataSetChanged();
							} else {
								Toast.makeText(CounterEditActivity.this,
										"削除に失敗しました", Toast.LENGTH_LONG).show(); // TODO
							}
						} catch (SQLiteException e) {
							e.printStackTrace();
							Toast.makeText(CounterEditActivity.this,
									e.getMessage(), Toast.LENGTH_LONG).show();
							CounterEditActivity.this.finish();
						}
					}

				}
			})
			.create().show();
		}
	}

	/**
	 * ListAdapterの初期化を行う。
	 *
	 * @throws SQLiteException
	 */
	private void initAdapter() throws SQLiteException {
		SQLiteDatabase db = mHelper.getReadableDatabase();

		Cursor cursor = null;
		try {
			final String[] columns = null;
			final String selection = "ContributeDate=?"
					+ " AND PlaceId=? AND TimeId=? AND Memo=? AND UploadDate IS NULL";
			final String[] selectionArgs = { mDate, mPlace, mTime, mMemo };
			final String groupBy = null;
			final String having = null;
			final String orderBy = "Id ASC";

			cursor = db.query("Counter", columns,
					selection, selectionArgs, groupBy, having, orderBy);

			List<Counter> list = new ArrayList<Counter>(cursor.getCount());
			while (cursor.moveToNext()) {
				list.add(new Counter(cursor));
			}

			if (mAdapter == null) {
				mAdapter = new ListAdapter(this, list);
			} else {
				mAdapter.setData(list);
				mAdapter.notifyDataSetChanged();
			}
		} finally {
			if (cursor != null) cursor.close();
		}
	}

	/**
	 * DBから特定行を削除する
	 *
	 * @param counter
	 * @return
	 * @throws SQLiteException
	 */
	private boolean deleteItemFromDB(Counter counter) throws SQLiteException {
		final String whereClause = "Id=? AND UploadDate IS NULL";
		final String[] whereArgs = { counter.getId() };

		SQLiteDatabase db = mHelper.getWritableDatabase();
		db.beginTransaction();
		try {
			int rows = db.delete("Counter", whereClause, whereArgs);
			db.setTransactionSuccessful();

			return rows == 1 ? true : false;
		} catch (IllegalStateException e) {
			e.printStackTrace();
			return false;
		} finally {
			db.endTransaction();
		}
	}

	/**
	 * DB上データの日時・時間更新。トランザクション失敗時にFALSEを返す。
	 *
	 * @param date
	 * @param time
	 * @param place
	 * @param memo
	 * @return
	 * @throws SQLiteException
	 */
	private boolean updateItemInDB(String date,
			String time, String place, String memo) throws SQLiteException {

		final ContentValues values = new ContentValues();
		values.put("ContributeDate", date);
		values.put("TimeId", time);
		values.put("PlaceId", place);
		values.put("Memo", memo);
		final String whereClause = "ContributeDate=? AND TimeId=? "
				+ "AND PlaceId=? AND Memo=? AND UploadDate IS NULL";
		final String[] whereArgs = {mDate, mTime, mPlace, mMemo};

		SQLiteDatabase db = mHelper.getWritableDatabase();
		db.beginTransaction();
		try {
			db.update("Counter", values, whereClause, whereArgs);
			db.setTransactionSuccessful();
			return true;
		} catch (IllegalStateException e) {
			e.printStackTrace();
			return false;
		} finally {
			db.endTransaction();
		}
	}

	/**
	 * タイトル部分のTextView表示内容変更
	 */
	private void initTextView() {
		// 日時
		String date = "";
		try {
			date = new SimpleDateFormat("MM月dd日").format(
					new SimpleDateFormat("yyyy-MM-dd").parse(mDate));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		date += "　";
		date += Common.getTimeList().get(mTime).getName();

		String place = Common.getPlaceList().get(mPlace).getName();


		TextView textDate = (TextView) findViewById(R.id.text_date);
		textDate.setText(date);

		TextView textPlace = (TextView) findViewById(R.id.text_place);
		textPlace.setText(place);
	}

	/**
	 * 編集画面のリストのアダプター
	 *
	 * @author noxi
	 *
	 */
	static final class ListAdapter extends BaseAdapter {


		private Context mContext;
		private LayoutInflater mInflater;
		private List<Counter> mData;

		public ListAdapter(Context context, List<Counter> data) {
			mContext = context;
			mData = data;
			mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		public void setData(List<Counter> data) {
			mData = data;
		}

		public List<Counter> getData() {
			return mData;
		}

		public void remove(int position) {
			mData.remove(position);
		}

		@Override
		public int getCount() {
			return mData.size();
		}

		@Override
		public Counter getItem(int position) {
			return mData.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			TextView text;
			if (convertView == null) {
				convertView = mInflater.inflate(R.layout.listitem_counter_edit, parent, false);

				text = (TextView) convertView.findViewById(R.id.text);
				convertView.setTag(text);
			} else {
				text = (TextView) convertView.getTag();
			}

			Counter rowdata = mData.get(position);

			String details = Common.getUseList().get(rowdata.getUseId()).getName()
					+ "　" + mContext.getString(rowdata.getSex().equals("1") ?
							R.string.l_man : R.string.l_woman) + "\n";
			details += Common.getOccList().get(rowdata.getOccupationId()).getName()
					+ "　" +rowdata.getNum() + mContext.getString(R.string.l_people_unit) + "\n";
			details += "　" + rowdata.getDetailMemo();

			text.setText(details);
			return convertView;
		}

	}
}
